using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using Microsoft.Web.WebView2.Core;
using System.Security.Principal;
using System.Diagnostics;
using System.Reflection;

namespace MermaidTextEditor
{
    public enum PreviewMode
    {
        None,       // 关闭预览
        Mermaid,    // Mermaid 图表
        Markdown    // Markdown 预览
    }

    public partial class MainWindow : Window
    {
        // 常量定义
        private const string FILE_FILTER = "所有支持的文件 (*.txt;*.md;*.mmd)|*.txt;*.md;*.mmd|文本文件 (*.txt)|*.txt|Markdown文件 (*.md)|*.md|Mermaid文件 (*.mmd)|*.mmd|所有文件 (*.*)|*.*";
        
        // 私有字段
        private string? currentFilePath;
        private Encoding currentEncoding = new UTF8Encoding(false); // UTF-8 无BOM
        private bool isWebViewInitialized = false;
        private bool autoRender = true;
        private System.Timers.Timer? renderTimer;
        private PreviewMode currentPreviewMode = PreviewMode.None;
        private string? fileToLoadOnStartup = null;
        private static bool isEncodingProviderRegistered = false;

        public MainWindow()
        {
            InitializeComponent();
            
            // 确保编码提供器只注册一次
            EnsureEncodingProviderRegistered();
            
            // 设置自动渲染定时器
            renderTimer = new System.Timers.Timer(1000); // 1秒延迟
            renderTimer.Elapsed += async (s, e) =>
            {
                renderTimer.Stop();
                await Dispatcher.InvokeAsync(async () => await RenderPreview());
            };
            renderTimer.AutoReset = false;
        }
        
        // 确保编码提供器已注册（只注册一次）
        private static void EnsureEncodingProviderRegistered()
        {
            if (!isEncodingProviderRegistered)
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                isEncodingProviderRegistered = true;
            }
        }

        // 支持通过命令行参数打开文件的构造函数
        public MainWindow(string filePath) : this()
        {
            fileToLoadOnStartup = filePath;
        }

        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                Debug.WriteLine("=== Window_Loaded 开始 ===");
                
                // ✅ 先立即加载文本（不等WebView）
                if (!string.IsNullOrEmpty(fileToLoadOnStartup) && File.Exists(fileToLoadOnStartup))
                {
                    Debug.WriteLine($"✓ 立即加载文本: {fileToLoadOnStartup}");
                    OpenFileWithAutoDetect(fileToLoadOnStartup);
                    
                    Debug.WriteLine($"  → OpenFileWithAutoDetect 完成后，currentFilePath = {currentFilePath ?? "(null)"}");
                    
                    // 立即检测并设置预览模式
                    var detectedMode = DetectPreviewModeFromFile();
                    Debug.WriteLine($"  → DetectPreviewModeFromFile 返回: {detectedMode}");
                    
                    currentPreviewMode = detectedMode;
                    Debug.WriteLine($"✓ 设置 currentPreviewMode = {currentPreviewMode}");
                }
                
                // 初始化WebView（文本已显示，慢慢加载）
                await InitializeWebView();
                Debug.WriteLine($"✓ WebView初始化完成");
                
                // WebView就绪后，如果有文件，自动打开预览并渲染
                Debug.WriteLine($"→ 检查是否自动打开预览:");
                Debug.WriteLine($"   currentFilePath = {currentFilePath ?? "(null)"}");
                Debug.WriteLine($"   currentPreviewMode = {currentPreviewMode}");
                Debug.WriteLine($"   PreviewColumn.Width = {PreviewColumn.Width.Value}");
                
                if (!string.IsNullOrEmpty(currentFilePath) && currentPreviewMode != PreviewMode.None)
                {
                    Debug.WriteLine($"✓ 条件满足，自动打开预览并渲染，mode={currentPreviewMode}");
                    
                    // ✅ 关键修复：无论预览窗格是否已打开，都要调用 SetPreviewMode
                    // 因为需要设置 PreviewModeText 和执行渲染
                    Debug.WriteLine($"  → 调用 SetPreviewMode({currentPreviewMode})");
                    await SetPreviewMode(currentPreviewMode);
                    
                    // 注意：SetPreviewMode内部会调用渲染，所以不需要额外调用RenderPreview
                }
                else
                {
                    Debug.WriteLine($"✗ 条件不满足，跳过自动预览");
                    if (string.IsNullOrEmpty(currentFilePath))
                        Debug.WriteLine($"   原因：currentFilePath 为空");
                    if (currentPreviewMode == PreviewMode.None)
                        Debug.WriteLine($"   原因：currentPreviewMode 是 None");
                }
                
                Debug.WriteLine("=== Window_Loaded 完成 ===");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"✗ Window_Loaded 异常: {ex.Message}");
                RenderProgressBar.Visibility = Visibility.Collapsed;
                MessageBox.Show($"初始化失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // 加载文件的方法（用于启动时打开文件）
        private async void LoadFile(string filePath)
        {
            if (!File.Exists(filePath))
            {
                MessageBox.Show($"文件不存在: {filePath}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            
            Debug.WriteLine($"准备加载文件: {filePath}");
            Debug.WriteLine($"当前 isWebViewInitialized = {isWebViewInitialized}");
            
            // ✅ 优化方案：先加载文本内容，让用户立即看到文件
            Debug.WriteLine("立即加载文本内容...");
            OpenFileWithAutoDetect(filePath);
            
            // ✅ 关键修复：根据文件类型自动检测预览模式
            var detectedMode = DetectPreviewModeFromFile();
            Debug.WriteLine($"检测到文件类型预览模式: {detectedMode}");
            Debug.WriteLine($"  currentFilePath = {currentFilePath}");
            
            // ⚠️ 如果检测失败，不要设置为None
            if (detectedMode != PreviewMode.None)
            {
                currentPreviewMode = detectedMode;
                Debug.WriteLine($"✓ 设置 currentPreviewMode = {currentPreviewMode}");
            }
            else
            {
                Debug.WriteLine($"⚠️ 检测结果是None，保持原值 currentPreviewMode = {currentPreviewMode}");
            }
            
            // 如果预览组件未初始化，在后台等待并自动打开预览
            if (!isWebViewInitialized)
            {
                Debug.WriteLine("预览组件尚未初始化，后台等待中...");
                StatusText.Text = "文件已加载，预览组件正在初始化...";
                
                // 显示预览框，内容会显示等待信息
                if (PreviewColumn.Width.Value == 0)
                {
                    await SetPreviewMode(currentPreviewMode);
                }
                
                // 在后台等待初始化完成
                _ = Task.Run(async () =>
                {
                    int retries = 0;
                    while (!isWebViewInitialized && retries < 30)
                    {
                        await Task.Delay(1000);
                        retries++;
                        
                        if (retries % 5 == 0)
                        {
                            Debug.WriteLine($"后台等待预览组件初始化... ({retries}/30秒)");
                            await Dispatcher.InvokeAsync(() =>
                            {
                                StatusText.Text = $"预览组件初始化中... ({retries}秒)";
                            });
                        }
                    }
                    
                    // 初始化完成后自动渲染预览
                    await Dispatcher.InvokeAsync(async () =>
                    {
                        if (isWebViewInitialized)
                        {
                            Debug.WriteLine($"✓ 预览组件已就绪（等待了 {retries} 秒），自动渲染预览");
                            StatusText.Text = "预览组件已就绪，开始渲染...";
                            await RenderPreview();
                        }
                        else
                        {
                            Debug.WriteLine("✗ 预览组件初始化超时");
                            StatusText.Text = "⚠ 预览组件初始化超时";
                        }
                    });
                });
            }
            else
            {
                // 已初始化，立即打开预览
                Debug.WriteLine("预览组件已就绪，立即显示预览");
                if (PreviewColumn.Width.Value == 0)
                {
                    await SetPreviewMode(currentPreviewMode);
                }
                await RenderPreview();
            }
        }

        private async void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            // F5 快捷键刷新预览或重置缩放
            if (e.Key == System.Windows.Input.Key.F5)
            {
                e.Handled = true;
                
                try
                {
                    // 立即显示进度条和状态信息，让用户知道操作正在进行
                    RenderProgressBar.Visibility = Visibility.Visible;
                    StatusText.Text = "正在准备预览...";
                    
                    // 强制更新UI，确保进度条立即显示
                    await Dispatcher.InvokeAsync(() => { }, System.Windows.Threading.DispatcherPriority.Render);
                    
                    // 如果预览已关闭，根据文件后缀自动选择预览模式
                    if (currentPreviewMode == PreviewMode.None)
                    {
                        PreviewMode targetMode = DetectPreviewModeFromFile();
                        await SetPreviewMode(targetMode);
                        
                        // 确保立即渲染一次（SetPreviewMode 内部的渲染可能因各种原因未执行）
                        // 由于外层已经显示进度条，这里不再重复显示
                        await RenderPreview(showProgress: false);
                        StatusText.Text = $"已自动启用{GetPreviewModeName()}预览 (F5)";
                    }
                    else
                    {
                        // 预览已开启，先重置缩放，然后刷新内容
                        await ResetPreviewZoom();
                        await RenderPreview(showProgress: false);
                        StatusText.Text = "已重置并刷新预览 (F5)";
                    }
                }
                finally
                {
                    // 确保进度条最终会被隐藏
                    RenderProgressBar.Visibility = Visibility.Collapsed;
                }
            }
        }

        private PreviewMode DetectPreviewModeFromFile()
        {
            Debug.WriteLine($"=== DetectPreviewModeFromFile 调用 ===");
            Debug.WriteLine($"  currentFilePath = {currentFilePath ?? "(null)"}");
            
            // 根据当前文件后缀判断预览模式
            if (!string.IsNullOrEmpty(currentFilePath))
            {
                string extension = Path.GetExtension(currentFilePath).ToLower();
                Debug.WriteLine($"  扩展名 = {extension}");
                
                var result = extension switch
                {
                    ".md" => PreviewMode.Markdown,
                    ".mmd" => PreviewMode.Mermaid,
                    _ => PreviewMode.Markdown  // 默认使用 Markdown
                };
                
                Debug.WriteLine($"  返回 = {result}");
                return result;
            }
            
            // 没有打开文件，默认使用 Markdown
            Debug.WriteLine($"  currentFilePath 为空，返回 Markdown");
            return PreviewMode.Markdown;
        }

        // 重置预览缩放和位置
        private async Task ResetPreviewZoom()
        {
            if (!isWebViewInitialized)
            {
                Debug.WriteLine("⚠ ResetPreviewZoom: WebView未初始化");
                return;
            }

            try
            {
                string script = @"
                    (function() {
                        console.log('=== 开始重置缩放 ===');
                        if (typeof window.resetZoom === 'function') {
                            window.resetZoom();
                            console.log('✓ resetZoom() 已调用');
                            return 'success';
                        } else {
                            console.log('✗ window.resetZoom 函数不存在');
                            return 'no_function';
                        }
                    })();
                ";
                string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                result = result.Trim().Trim('"');
                Debug.WriteLine($"✓ 重置缩放完成，结果: {result}");
                
                if (result != "success")
                {
                    Debug.WriteLine($"⚠ 重置可能失败: {result}");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"✗ 重置缩放异常: {ex.Message}");
            }
        }

        // 保存当前缩放和平移状态
        private async Task<string> SaveZoomState()
        {
            if (!isWebViewInitialized)
                return "1,0,0";

            try
            {
                string script = @"
                    (function() {
                        var wrapper = document.getElementById('preview-wrapper');
                        if (!wrapper) return '1,0,0';
                        var scale = wrapper.dataset.scale || '1';
                        var translateX = wrapper.dataset.translateX || '0';
                        var translateY = wrapper.dataset.translateY || '0';
                        return scale + ',' + translateX + ',' + translateY;
                    })();
                ";
                string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                result = result.Trim().Trim('"');
                Debug.WriteLine($"保存缩放状态: {result}");
                return result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"保存缩放状态失败: {ex.Message}");
                return "1,0,0";
            }
        }

        // 恢复缩放和平移状态
        private async Task RestoreZoomState(string state)
        {
            if (!isWebViewInitialized || string.IsNullOrEmpty(state))
                return;

            try
            {
                var parts = state.Split(',');
                if (parts.Length != 3)
                {
                    Debug.WriteLine($"无效的状态字符串: {state}");
                    return;
                }

                string script = $@"
                    (function() {{
                        if (typeof window.restoreZoom === 'function') {{
                            window.restoreZoom({parts[0]}, {parts[1]}, {parts[2]});
                            return 'success';
                        }}
                        return 'no_function';
                    }})();
                ";
                string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                result = result.Trim().Trim('"');
                Debug.WriteLine($"恢复缩放状态: {result}");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"恢复缩放状态失败: {ex.Message}");
            }
        }

        private async Task InitializeWebView()
        {
            try
            {
                // 确保 WebView2 运行时可用
                var userDataFolder = Path.Combine(Path.GetTempPath(), "MermaidTextEditor_WebView2");
                var environment = await CoreWebView2Environment.CreateAsync(null, userDataFolder, null);
                
                await PreviewWebView.EnsureCoreWebView2Async(environment);
                
                // 禁用上下文菜单，启用开发者工具用于调试
                PreviewWebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
                PreviewWebView.CoreWebView2.Settings.AreDevToolsEnabled = true;
                
                // 监听控制台消息
                PreviewWebView.CoreWebView2.WebMessageReceived += (s, e) =>
                {
                    Debug.WriteLine($"WebView消息: {e.TryGetWebMessageAsString()}");
                };
                
                // 监听导航完成
                PreviewWebView.CoreWebView2.NavigationCompleted += (s, e) =>
                {
                    Debug.WriteLine($"导航完成: Success={e.IsSuccess}, WebErrorStatus={e.WebErrorStatus}");
                };
                
                StatusText.Text = "正在加载预览组件...";
                
                // 提取嵌入的JavaScript库到本地
                await ExtractEmbeddedLibraries();
                
                // 设置虚拟主机映射，让本地文件可以通过虚拟URL访问
                SetupVirtualHostMapping();
                
                // 加载HTML页面
                await LoadPreviewHTML();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"WebView2 初始化失败: {ex.Message}\n\n请确保已安装 WebView2 Runtime。", 
                    "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                throw;
            }
        }

        // 提取嵌入的JavaScript库文件
        private async Task ExtractEmbeddedLibraries()
        {
            try
            {
                var assembly = Assembly.GetExecutingAssembly();
                var resourceNames = assembly.GetManifestResourceNames()
                    .Where(name => name.Contains(".Resources.js.") && name.EndsWith(".js"))
                    .ToArray();

                if (resourceNames.Length == 0)
                {
                    // 没有嵌入的资源，尝试使用外部文件
                    Debug.WriteLine("⚠ 未找到嵌入的库文件，将使用CDN");
                    StatusText.Text = "未找到嵌入的库文件，将使用CDN...";
                    return;
                }
                
                Debug.WriteLine($"✓ 发现 {resourceNames.Length} 个嵌入的JS库文件");

                var libDir = Path.Combine(Path.GetTempPath(), "MermaidTextEditor_Libs");
                if (!Directory.Exists(libDir))
                {
                    Directory.CreateDirectory(libDir);
                }

                foreach (var resourceName in resourceNames)
                {
                    // 正确提取文件名：从 ".js." 后面开始
                    // 例如: MermaidTextEditor.Resources.js.mermaid.min.js → mermaid.min.js
                    var marker = ".js.";
                    var markerIndex = resourceName.IndexOf(marker);
                    var fileName = markerIndex >= 0 
                        ? resourceName.Substring(markerIndex + marker.Length) 
                        : resourceName.Split('.').Last();
                    var targetPath = Path.Combine(libDir, fileName);

                    // 如果文件已存在且大小正确，跳过
                    using (var resourceStream = assembly.GetManifestResourceStream(resourceName))
                    {
                        if (resourceStream != null)
                        {
                            if (File.Exists(targetPath))
                            {
                                var existingFileInfo = new FileInfo(targetPath);
                                if (existingFileInfo.Length == resourceStream.Length)
                                {
                                    continue; // 文件已存在且大小匹配
                                }
                            }

                            using (var fileStream = File.Create(targetPath))
                            {
                                await resourceStream.CopyToAsync(fileStream);
                                Debug.WriteLine($"✓ 提取文件: {fileName} ({resourceStream.Length} bytes) -> {targetPath}");
                            }
                        }
                    }
                }

                Debug.WriteLine($"✓ 所有库文件已提取到: {libDir}");
                StatusText.Text = "JavaScript库已准备就绪（本地模式）";
            }
            catch (Exception ex)
            {
                // 提取失败不是致命错误，应用仍可使用CDN
                Debug.WriteLine($"提取嵌入库失败: {ex.Message}");
                StatusText.Text = "本地库提取失败，将使用CDN...";
            }
        }

        // 设置虚拟主机映射
        private void SetupVirtualHostMapping()
        {
            try
            {
                var libDir = Path.Combine(Path.GetTempPath(), "MermaidTextEditor_Libs");
                
                if (Directory.Exists(libDir) && Directory.GetFiles(libDir, "*.js").Length > 0)
                {
                    // 将本地目录映射到虚拟主机 http://local.mermaid/
                    PreviewWebView.CoreWebView2.SetVirtualHostNameToFolderMapping(
                        "local.mermaid",
                        libDir,
                        CoreWebView2HostResourceAccessKind.Allow
                    );
                    
                    Debug.WriteLine($"✓ 虚拟主机映射已设置: local.mermaid -> {libDir}");
                    
                    // 列出映射的文件
                    var files = Directory.GetFiles(libDir, "*.js");
                    foreach (var file in files)
                    {
                        var fi = new FileInfo(file);
                        Debug.WriteLine($"  - {fi.Name} ({fi.Length} bytes)");
                    }
                }
                else
                {
                    Debug.WriteLine($"⚠ 无法设置虚拟主机映射: 目录不存在或为空");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"✗ 设置虚拟主机映射失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 如果有文件已打开且预览窗格未打开，自动打开预览并渲染
        /// </summary>
        // 加载预览HTML页面
        private async Task LoadPreviewHTML()
        {
            // 加载包含 Mermaid 和 Markdown 的 HTML (优先使用本地文件)
            string html = @"
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <script>
        // 优先使用本地文件，失败时使用CDN
        (function() {
            // 本地文件路径（通过虚拟主机）
            var localUrls = [
                'http://local.mermaid/marked.min.js',
                'http://local.mermaid/marked.js'
            ];
            // CDN备用地址
            var cdnUrls = [
                'https://cdn.jsdelivr.net/npm/marked@11.0.0/marked.min.js',
                'https://unpkg.com/marked@11.0.0/marked.min.js',
                'https://cdnjs.cloudflare.com/ajax/libs/marked/11.0.0/marked.min.js'
            ];
            
            var allUrls = localUrls.concat(cdnUrls);
            var loaded = false;
            
            function tryLoad(index) {
                if (index >= allUrls.length) {
                    console.error('Failed to load marked.js from all sources');
                    return;
                }
                var script = document.createElement('script');
                script.src = allUrls[index];
                script.onload = function() { 
                    loaded = true; 
                    var source = index < localUrls.length ? '本地缓存' : 'CDN';
                    console.log('Marked.js loaded from: ' + source + ' (' + allUrls[index] + ')');
                };
                script.onerror = function() { 
                    console.log('Failed to load from: ' + allUrls[index]);
                    tryLoad(index + 1); 
                };
                document.head.appendChild(script);
            }
            tryLoad(0);
        })();
    </script>
    <script>
        // 加载 Mermaid（使用非ESM版本以支持离线）
        (function() {
            // 本地文件路径
            var localUrls = [
                'http://local.mermaid/mermaid.min.js',
                'http://local.mermaid/mermaid.js'
            ];
            // CDN备用地址
            var cdnUrls = [
                'https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js',
                'https://unpkg.com/mermaid@10.6.1/dist/mermaid.min.js'
            ];
            
            var allUrls = localUrls.concat(cdnUrls);
            var loaded = false;
            
            function tryLoad(index) {
                if (index >= allUrls.length) {
                    console.error('Failed to load mermaid.js from all sources');
                    return;
                }
                var script = document.createElement('script');
                script.src = allUrls[index];
                script.onload = function() { 
                    loaded = true;
                    var source = index < localUrls.length ? '本地缓存' : 'CDN';
                    console.log('Mermaid.js loaded from: ' + source + ' (' + allUrls[index] + ')');
                    
                    // 初始化 Mermaid
                    if (window.mermaid) {
                        window.mermaid.initialize({ 
                startOnLoad: false,
                theme: 'default',
                securityLevel: 'loose'
            });
                    }
                };
                script.onerror = function() { 
                    console.log('Failed to load from: ' + allUrls[index]);
                    tryLoad(index + 1); 
                };
                document.head.appendChild(script);
            }
            tryLoad(0);
        })();
        
        // 渲染函数
        window.renderMermaid = async function(code) {
            try {
                if (!window.mermaid) {
                    throw new Error('Mermaid library not loaded');
                }
                const container = document.getElementById('preview-container');
                const id = 'mermaid-' + Date.now();
                const { svg } = await window.mermaid.render(id, code);
                container.innerHTML = svg;
                return 'success';
            } catch(err) {
                document.getElementById('preview-container').innerHTML = '<pre style=""color: red;"">' + err.message + '</pre>';
                return 'error: ' + err.message;
            }
        };
        
        window.renderMarkdown = function(markdown) {
            try {
                if (!window.marked) {
                    throw new Error('Marked library not loaded');
                }
                const container = document.getElementById('preview-container');
                container.innerHTML = marked.parse(markdown);
                return 'success';
            } catch(err) {
                document.getElementById('preview-container').innerHTML = '<pre style=""color: red;"">' + err.message + '</pre>';
                return 'error: ' + err.message;
            }
        };
    </script>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
            line-height: 1.6;
            overflow: hidden;
            width: 100vw;
            height: 100vh;
        }
        #preview-wrapper {
            width: 100%;
            height: 100%;
            overflow: hidden;
            position: relative;
            cursor: grab;
        }
        #preview-wrapper.dragging {
            cursor: grabbing;
        }
        #preview-container {
            max-width: 100%;
            padding: 20px;
            transform-origin: 0 0;
            transition: transform 0.1s ease-out;
        }
        /* Markdown 样式 */
        h1, h2, h3, h4, h5, h6 {
            margin-top: 24px;
            margin-bottom: 16px;
            font-weight: 600;
            line-height: 1.25;
        }
        h1 { font-size: 2em; border-bottom: 1px solid #eaecef; padding-bottom: 0.3em; }
        h2 { font-size: 1.5em; border-bottom: 1px solid #eaecef; padding-bottom: 0.3em; }
        h3 { font-size: 1.25em; }
        code {
            background-color: #f6f8fa;
            border-radius: 3px;
            padding: 2px 4px;
            font-family: Consolas, Monaco, monospace;
        }
        pre {
            background-color: #f6f8fa;
            border-radius: 3px;
            padding: 16px;
            overflow: auto;
        }
        pre code {
            background-color: transparent;
            padding: 0;
        }
        blockquote {
            border-left: 4px solid #dfe2e5;
            padding-left: 16px;
            color: #6a737d;
            margin: 0;
        }
        table {
            border-collapse: collapse;
            width: 100%;
        }
        table th, table td {
            border: 1px solid #dfe2e5;
            padding: 6px 13px;
        }
        table tr:nth-child(2n) {
            background-color: #f6f8fa;
        }
        img {
            max-width: 100%;
        }
        a {
            color: #0366d6;
            text-decoration: none;
        }
        a:hover {
            text-decoration: underline;
        }
        /* 加载动画 */
        .loading {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 400px;
            color: #666;
        }
        .spinner {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #3498db;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin-bottom: 20px;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div id='preview-wrapper'>
        <div id='preview-container'>
            <div class='loading'>
                <div class='spinner'></div>
                <p>正在加载预览组件...</p>
                <small style='color: #999;'>脚本正在初始化中，请稍候</small>
            </div>
        </div>
    </div>
    <script>
        // 缩放和平移功能
        (function() {
            var wrapper = document.getElementById('preview-wrapper');
            var container = document.getElementById('preview-container');
            
            // 状态变量
            var scale = 1;
            var translateX = 0;
            var translateY = 0;
            var isDragging = false;
            var startX = 0;
            var startY = 0;
            var lastTranslateX = 0;
            var lastTranslateY = 0;
            
            // 更新transform
            function updateTransform() {
                var transformValue = 'translate(' + translateX + 'px, ' + translateY + 'px) scale(' + scale + ')';
                container.style.transform = transformValue;
                // 保存状态到dataset
                wrapper.dataset.scale = scale.toString();
                wrapper.dataset.translateX = translateX.toString();
                wrapper.dataset.translateY = translateY.toString();
                console.log('Transform更新: ' + transformValue);
            }
            
            // 鼠标滚轮缩放
            wrapper.addEventListener('wheel', function(e) {
                e.preventDefault();
                
                // 获取鼠标在容器中的位置
                var rect = wrapper.getBoundingClientRect();
                var mouseX = e.clientX - rect.left;
                var mouseY = e.clientY - rect.top;
                
                // 计算鼠标在内容中的位置（缩放前）
                var contentX = (mouseX - translateX) / scale;
                var contentY = (mouseY - translateY) / scale;
                
                // 计算新的缩放比例（向上滚动放大，向下滚动缩小）
                var delta = e.deltaY < 0 ? 0.1 : -0.1;
                var newScale = Math.max(0.1, Math.min(5, scale + delta));
                
                // 计算新的平移值，使鼠标位置保持不变
                translateX = mouseX - contentX * newScale;
                translateY = mouseY - contentY * newScale;
                
                scale = newScale;
                updateTransform();
            }, { passive: false });
            
            // 鼠标左键拖拽平移
            wrapper.addEventListener('mousedown', function(e) {
                if (e.button === 0) { // 左键
                    isDragging = true;
                    wrapper.classList.add('dragging');
                    startX = e.clientX;
                    startY = e.clientY;
                    lastTranslateX = translateX;
                    lastTranslateY = translateY;
                    e.preventDefault();
                }
            });
            
            document.addEventListener('mousemove', function(e) {
                if (isDragging) {
                    var deltaX = e.clientX - startX;
                    var deltaY = e.clientY - startY;
                    translateX = lastTranslateX + deltaX;
                    translateY = lastTranslateY + deltaY;
                    updateTransform();
                }
            });
            
            document.addEventListener('mouseup', function(e) {
                if (e.button === 0 && isDragging) {
                    isDragging = false;
                    wrapper.classList.remove('dragging');
                }
            });
            
            // 重置缩放和位置
            window.resetZoom = function() {
                console.log('执行 resetZoom: scale=' + scale + ', translateX=' + translateX + ', translateY=' + translateY);
                scale = 1;
                translateX = 0;
                translateY = 0;
                updateTransform();
                console.log('重置完成: scale=' + scale + ', translateX=' + translateX + ', translateY=' + translateY);
            };
            
            // 恢复缩放和位置
            window.restoreZoom = function(newScale, newTranslateX, newTranslateY) {
                console.log('恢复缩放状态: scale=' + newScale + ', translateX=' + newTranslateX + ', translateY=' + newTranslateY);
                scale = parseFloat(newScale);
                translateX = parseFloat(newTranslateX);
                translateY = parseFloat(newTranslateY);
                updateTransform();
                console.log('恢复完成');
            };
            
            // 初始化
            updateTransform();
        })();
    </script>
</body>
</html>";
            
            try
            {
                Debug.WriteLine("开始加载HTML页面...");
                
                // ✅ 显示进度条
                RenderProgressBar.Visibility = Visibility.Visible;
                StatusText.Text = "正在加载预览组件...";
                
                PreviewWebView.NavigateToString(html);
                
                // 强制刷新UI
                await Dispatcher.InvokeAsync(() => { }, System.Windows.Threading.DispatcherPriority.Render);
                
                // 等待页面加载完成（缩短时间）
                Debug.WriteLine("等待1秒以加载页面...");
                await Task.Delay(1000);  // 缩短为1秒
                
                // 检测 JavaScript 库是否加载成功
                StatusText.Text = "检测脚本加载状态...";
                bool scriptsLoaded = await CheckScriptsLoaded();
                
                if (scriptsLoaded)
                {
                    isWebViewInitialized = true;
                    RenderProgressBar.Visibility = Visibility.Collapsed;
                    Debug.WriteLine("✓ 预览组件初始化成功");
                    StatusText.Text = "预览组件已就绪 ✓";
                    
                    // ⚠️ 不在这里自动渲染，让 Window_Loaded 统一控制
                    Debug.WriteLine("  → 初始化完成，等待 Window_Loaded 控制渲染");
                }
                else
                {
                    Debug.WriteLine("⚠ 首次检查失败，等待2秒后重试...");
                    StatusText.Text = "⚠ 脚本加载中，请稍候... (重试 1/2)";
                    // 缩短等待时间
                    await Task.Delay(2000);  // 从3秒缩短为2秒
                    scriptsLoaded = await CheckScriptsLoaded();
                    
                    if (scriptsLoaded)
                    {
                        isWebViewInitialized = true;
                        RenderProgressBar.Visibility = Visibility.Collapsed;
                        Debug.WriteLine("✓ 预览组件初始化成功（第2次尝试）");
                        StatusText.Text = "预览组件已就绪 ✓";
                    }
                    else
                    {
                        Debug.WriteLine("⚠ 第2次检查失败，最后尝试...");
                        StatusText.Text = "⚠ 脚本加载中，请稍候... (重试 2/2)";
                        // 缩短最后等待时间
                        await Task.Delay(3000);  // 从5秒缩短为3秒
                        scriptsLoaded = await CheckScriptsLoaded();
                        
                        if (scriptsLoaded)
                        {
                        isWebViewInitialized = true;
                            RenderProgressBar.Visibility = Visibility.Collapsed;
                            Debug.WriteLine("✓ 预览组件初始化成功（第3次尝试）");
                            StatusText.Text = "预览组件已就绪 ✓";
                        }
                        else
                        {
                            Debug.WriteLine("✗ 所有尝试都失败了，但仍标记为已初始化，允许用户尝试");
                            RenderProgressBar.Visibility = Visibility.Collapsed;
                            // 关键修复：即使脚本加载失败，也标记为已初始化
                            isWebViewInitialized = true;
                            StatusText.Text = "⚠ 脚本加载较慢，请按 F5 尝试预览";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载预览页面失败: {ex.Message}", 
                    "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                throw;
            }
        }

        private async Task<bool> CheckScriptsLoaded()
        {
            try
            {
                // 检查 marked 是否存在
                string checkMarked = "typeof marked !== 'undefined' ? 'true' : 'false'";
                string markedResult = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(checkMarked);
                
                // 检查 mermaid 是否存在
                string checkMermaid = "typeof window.mermaid !== 'undefined' ? 'true' : 'false'";
                string mermaidResult = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(checkMermaid);
                
                bool markedLoaded = markedResult.Trim().Trim('"') == "true";
                bool mermaidLoaded = mermaidResult.Trim().Trim('"') == "true";
                
                Debug.WriteLine($"脚本加载状态: Marked={markedLoaded}, Mermaid={mermaidLoaded}");
                StatusText.Text = $"脚本状态: Marked={markedLoaded} Mermaid={mermaidLoaded}";
                
                return markedLoaded && mermaidLoaded;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"检查脚本加载失败: {ex.Message}");
                return false;
            }
        }

        private void TextEditor_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (autoRender && isWebViewInitialized && currentPreviewMode != PreviewMode.None)
            {
                renderTimer?.Stop();
                renderTimer?.Start();
            }
        }

        private async void ManualRefresh_Click(object sender, RoutedEventArgs e)
        {
            await RenderPreview();
        }

        private async Task RenderPreview(bool showProgress = true)
        {
            Debug.WriteLine($"=== RenderPreview 调用 ===");
            Debug.WriteLine($"  currentPreviewMode = {currentPreviewMode}");
            Debug.WriteLine($"  showProgress = {showProgress}");
            
            if (currentPreviewMode == PreviewMode.Mermaid)
            {
                Debug.WriteLine("  → 渲染 Mermaid");
                await RenderMermaid(showProgress);
            }
            else if (currentPreviewMode == PreviewMode.Markdown)
            {
                Debug.WriteLine("  → 渲染 Markdown");
                await RenderMarkdown(showProgress);
            }
            else
            {
                Debug.WriteLine($"  ⚠ 预览模式为 None，跳过渲染");
            }
        }

        private async Task RenderMermaid(bool showProgress = true)
        {
            if (!isWebViewInitialized)
            {
                StatusText.Text = "预览组件尚未初始化";
                return;
            }

            try
            {
                // 显示进度条（如果需要）
                if (showProgress)
                {
                    RenderProgressBar.Visibility = Visibility.Visible;
                    StatusText.Text = "正在渲染 Mermaid 图表...";
                }
                
                string mermaidCode = TextEditor.Text;
                if (string.IsNullOrWhiteSpace(mermaidCode))
                {
                    mermaidCode = "graph TD\n    A[开始编辑]\n    B[实时预览]\n    A --> B";
                }

                // 转义特殊字符
                string escapedCode = System.Text.Json.JsonSerializer.Serialize(mermaidCode);
                
                Debug.WriteLine($"准备渲染 Mermaid，代码长度: {mermaidCode.Length}");
                string script = $"window.renderMermaid({escapedCode})";
                string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                
                Debug.WriteLine($"Mermaid 渲染结果: {result}");
                
                // 检查渲染结果
                if (result.Contains("error"))
                {
                    // 渲染失败
                    var errorMsg = result.Replace("\"", "").Replace("error: ", "");
                    StatusText.Text = $"❌ Mermaid渲染失败";
                    Debug.WriteLine($"✗ Mermaid 渲染失败: {errorMsg}");
                    
                    // 在预览窗格中显示友好的错误提示
                    string errorHtml = $@"
                        <div style='padding: 40px; font-family: Arial, sans-serif;'>
                            <div style='background: #fff3cd; border-left: 4px solid #ffc107; padding: 20px; border-radius: 4px;'>
                                <h3 style='color: #856404; margin: 0 0 15px 0;'>
                                    ⚠️ Mermaid 渲染失败
                                </h3>
                                <p style='color: #856404; margin: 0 0 15px 0; font-size: 14px;'>
                                    <strong>错误信息：</strong><br/>
                                    {System.Web.HttpUtility.HtmlEncode(errorMsg)}
                                </p>
                                <details style='color: #856404; margin-top: 20px;'>
                                    <summary style='cursor: pointer; font-weight: bold;'>🔍 可能的原因</summary>
                                    <ul style='margin: 10px 0; padding-left: 20px;'>
                                        <li>Mermaid 语法错误</li>
                                        <li>不支持的图表类型</li>
                                        <li>节点或关系定义错误</li>
                                    </ul>
                                </details>
                                <details style='color: #856404; margin-top: 10px;'>
                                    <summary style='cursor: pointer; font-weight: bold;'>💡 解决建议</summary>
                                    <ul style='margin: 10px 0; padding-left: 20px;'>
                                        <li>检查 Mermaid 语法是否正确</li>
                                        <li>参考 <a href='https://mermaid.js.org/' target='_blank'>Mermaid 官方文档</a></li>
                                        <li>按 F5 重新渲染</li>
                                    </ul>
                                </details>
                            </div>
                        </div>";
                    
                    string setErrorScript = $@"
                        document.getElementById('preview-container').innerHTML = {System.Text.Json.JsonSerializer.Serialize(errorHtml)};
                    ";
                    await PreviewWebView.CoreWebView2.ExecuteScriptAsync(setErrorScript);
                }
                else
                {
                    // 验证内容是否真的渲染了
                    string checkScript = "document.getElementById('preview-container').innerHTML.length";
                    string contentLength = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(checkScript);
                    Debug.WriteLine($"容器内容长度: {contentLength}");
                    
                    if (contentLength == "0" || contentLength == "48") // 48 是占位文本的长度
                    {
                        StatusText.Text = "⚠ 渲染完成但内容为空";
                        Debug.WriteLine("⚠ preview-container 内容为空！");
                        
                        // 显示提示信息
                        string emptyHtml = @"
                            <div style='padding: 40px; text-align: center; color: #999; font-family: Arial, sans-serif;'>
                                <h3>🎨 预览区域</h3>
                                <p>渲染已完成，但没有生成内容</p>
                                <p style='font-size: 12px; margin-top: 20px;'>请检查代码是否正确，或按 F5 重新渲染</p>
                            </div>";
                        
                        string setEmptyScript = $@"
                            document.getElementById('preview-container').innerHTML = {System.Text.Json.JsonSerializer.Serialize(emptyHtml)};
                        ";
                        await PreviewWebView.CoreWebView2.ExecuteScriptAsync(setEmptyScript);
                    }
                    else
                    {
                        StatusText.Text = "Mermaid 渲染成功 ✓";
                        Debug.WriteLine($"✓ Mermaid 渲染成功，内容长度: {contentLength}");
                    }
                }
            }
            catch (Exception ex)
            {
                StatusText.Text = $"Mermaid渲染失败: {ex.Message}";
                MessageBox.Show($"Mermaid渲染失败:\n{ex.Message}\n\n请检查：\n1. 网络连接是否正常\n2. Mermaid语法是否正确", 
                    "渲染错误", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            finally
            {
                // 隐藏进度条（如果需要）
                if (showProgress)
                {
                    RenderProgressBar.Visibility = Visibility.Collapsed;
                }
            }
        }

        private async Task RenderMarkdown(bool showProgress = true)
        {
            if (!isWebViewInitialized)
            {
                StatusText.Text = "预览组件尚未初始化";
                return;
            }

            try
            {
                // 显示进度条（如果需要）
                if (showProgress)
                {
                    RenderProgressBar.Visibility = Visibility.Visible;
                    StatusText.Text = "正在渲染 Markdown...";
                }
                
                string markdownText = TextEditor.Text;
                if (string.IsNullOrWhiteSpace(markdownText))
                {
                    markdownText = "# 欢迎使用 Markdown 编辑器\n\n开始编辑您的内容...\n\n- 支持**粗体**和*斜体*\n- 支持代码块\n- 支持表格和列表";
                }

                // 转义特殊字符
                string escapedText = System.Text.Json.JsonSerializer.Serialize(markdownText);
                
                string script = $"window.renderMarkdown({escapedText})";
                string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                
                StatusText.Text = "Markdown已渲染 ✓";
            }
            catch (Exception ex)
            {
                StatusText.Text = $"Markdown渲染失败: {ex.Message}";
                MessageBox.Show($"Markdown渲染失败:\n{ex.Message}\n\n请检查网络连接是否正常。", 
                    "渲染错误", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            finally
            {
                // 隐藏进度条（如果需要）
                if (showProgress)
                {
                    RenderProgressBar.Visibility = Visibility.Collapsed;
                }
            }
        }

        private void NewFile_Click(object sender, RoutedEventArgs e)
        {
            if (ConfirmSaveChanges())
            {
                TextEditor.Clear();
                currentFilePath = null;
                currentEncoding = new UTF8Encoding(false);
                UpdateEncodingInfo();
                StatusText.Text = "新建文件";
            }
        }

        private async void OpenFile_Click(object sender, RoutedEventArgs e)
        {
            if (!ConfirmSaveChanges())
                return;

            OpenFileDialog dialog = new OpenFileDialog
            {
                Filter = FILE_FILTER,
                FilterIndex = 1,  // 默认选择"所有支持的文件"
                Title = "打开文件"
            };

            if (dialog.ShowDialog() == true)
            {
                OpenFileWithAutoDetect(dialog.FileName);
                
                // ✅ 自动检测并设置预览模式
                currentPreviewMode = DetectPreviewModeFromFile();
                Debug.WriteLine($"✓ 打开文件后设置预览模式: {currentPreviewMode}");
                
                // ✅ 如果WebView已就绪，自动打开预览并渲染
                if (isWebViewInitialized && currentPreviewMode != PreviewMode.None)
                {
                    await SetPreviewMode(currentPreviewMode);
                }
            }
        }

        private async void OpenFileWithEncoding_Click(object sender, RoutedEventArgs e)
        {
            if (!ConfirmSaveChanges())
                return;

            OpenFileDialog dialog = new OpenFileDialog
            {
                Filter = FILE_FILTER,
                FilterIndex = 1,
                Title = "选择要打开的文件"
            };

            if (dialog.ShowDialog() == true)
            {
                // 显示编码选择对话框
                var encodingChoice = MessageBox.Show(
                    "选择打开文件的编码方式：\n\n" +
                    "【是】 - 自动检测编码\n" +
                    "【否】 - 手动选择编码\n" +
                    "【取消】 - 取消打开",
                    "选择编码",
                    MessageBoxButton.YesNoCancel,
                    MessageBoxImage.Question);

                if (encodingChoice == MessageBoxResult.Cancel)
                    return;

                if (encodingChoice == MessageBoxResult.Yes)
                {
                    OpenFileWithAutoDetect(dialog.FileName);
                }
                else
                {
                    ShowEncodingSelectionDialog(dialog.FileName);
                }
                
                // ✅ 自动检测并设置预览模式
                currentPreviewMode = DetectPreviewModeFromFile();
                
                // ✅ 如果WebView已就绪，自动打开预览并渲染
                if (isWebViewInitialized && currentPreviewMode != PreviewMode.None)
                {
                    await SetPreviewMode(currentPreviewMode);
                }
            }
        }

        private void ShowEncodingSelectionDialog(string filePath)
        {
            var window = new Window
            {
                Title = "选择文件编码",
                Width = 400,
                Height = 300,
                WindowStartupLocation = WindowStartupLocation.CenterOwner,
                Owner = this,
                ResizeMode = ResizeMode.NoResize
            };

            var stackPanel = new StackPanel { Margin = new Thickness(20) };
            
            stackPanel.Children.Add(new TextBlock 
            { 
                Text = "请选择文件编码：",
                FontSize = 14,
                FontWeight = FontWeights.Bold,
                Margin = new Thickness(0, 0, 0, 15)
            });

            var listBox = new ListBox
            {
                Height = 150,
                Margin = new Thickness(0, 0, 0, 15)
            };

            var encodingOptions = new[]
            {
                "UTF-8 (无BOM)",
                "UTF-8 (带BOM)",
                "GBK",
                "GB2312",
                "Unicode (UTF-16 LE)",
                "Unicode (UTF-16 BE)",
                "ASCII"
            };

            foreach (var enc in encodingOptions)
            {
                listBox.Items.Add(enc);
            }
            listBox.SelectedIndex = 0;

            stackPanel.Children.Add(listBox);

            var buttonPanel = new StackPanel 
            { 
                Orientation = Orientation.Horizontal,
                HorizontalAlignment = HorizontalAlignment.Right
            };

            var okButton = new Button 
            { 
                Content = "确定",
                Width = 80,
                Height = 30,
                Margin = new Thickness(0, 0, 10, 0),
                IsDefault = true
            };

            var cancelButton = new Button 
            { 
                Content = "取消",
                Width = 80,
                Height = 30,
                IsCancel = true
            };

            okButton.Click += (s, e) => 
            {
                window.DialogResult = true;
                window.Close();
            };

            buttonPanel.Children.Add(okButton);
            buttonPanel.Children.Add(cancelButton);
            stackPanel.Children.Add(buttonPanel);

            window.Content = stackPanel;

            if (window.ShowDialog() == true && listBox.SelectedItem != null)
            {
                string selected = listBox.SelectedItem.ToString() ?? "";
                Encoding? encoding = GetEncodingByName(selected);

                if (encoding != null)
                {
                    OpenFileWithSpecificEncoding(filePath, encoding);
                }
            }
        }

        private void OpenFileWithAutoDetect(string filePath)
            {
                try
                {
                    // 尝试检测编码
                currentEncoding = DetectEncoding(filePath);
                string content = File.ReadAllText(filePath, currentEncoding);
                    TextEditor.Text = content;
                currentFilePath = filePath;
                    UpdateEncodingInfo();
                StatusText.Text = $"已打开 (编码: {GetEncodingDisplayName(currentEncoding)}): {Path.GetFileName(filePath)}";
            }
            catch (Exception ex)
            {
                var retry = MessageBox.Show(
                    $"自动检测编码打开失败: {ex.Message}\n\n是否手动选择编码重试？",
                    "打开失败",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Warning);

                if (retry == MessageBoxResult.Yes)
                {
                    ShowEncodingSelectionDialog(filePath);
                }
            }
        }

        private void OpenFileWithSpecificEncoding(string filePath, Encoding encoding)
        {
            try
            {
                string content = File.ReadAllText(filePath, encoding);
                TextEditor.Text = content;
                currentFilePath = filePath;
                currentEncoding = encoding;
                UpdateEncodingInfo();
                StatusText.Text = $"已打开 (编码: {GetEncodingDisplayName(encoding)}): {Path.GetFileName(filePath)}";
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"打开文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

        // 根据编码名称获取 Encoding 对象
        private Encoding? GetEncodingByName(string encodingName)
        {
            return encodingName switch
            {
                "UTF-8 (无BOM)" => new UTF8Encoding(false),
                "UTF-8 (带BOM)" => new UTF8Encoding(true),
                "GBK" => Encoding.GetEncoding("GBK"),
                "GB2312" => Encoding.GetEncoding("GB2312"),
                "Unicode (UTF-16 LE)" => Encoding.Unicode,
                "Unicode (UTF-16 BE)" => Encoding.BigEndianUnicode,
                "ASCII" => Encoding.ASCII,
                _ => null
            };
        }

        // 获取编码的显示名称（统一方法）
        private string GetEncodingDisplayName(Encoding encoding)
        {
            if (encoding is UTF8Encoding utf8)
            {
                return utf8.GetPreamble().Length > 0 ? "UTF-8 (带BOM)" : "UTF-8 (无BOM)";
            }
            else if (encoding.CodePage == 936)
            {
                return "GBK";
            }
            else if (encoding.CodePage == 20936)
            {
                return "GB2312";
            }
            else if (encoding == Encoding.Unicode)
            {
                return "Unicode (UTF-16 LE)";
            }
            else if (encoding == Encoding.BigEndianUnicode)
            {
                return "Unicode (UTF-16 BE)";
            }
            else if (encoding == Encoding.ASCII)
            {
                return "ASCII";
            }
            return encoding.EncodingName;
        }

        // 重新加载当前文件的方法（统一处理）
        private void ReloadCurrentFile(string? encodingName = null)
        {
            if (string.IsNullOrEmpty(currentFilePath))
            {
                MessageBox.Show("当前没有打开的文件", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            
            if (encodingName == null)
            {
                // 自动检测
                OpenFileWithAutoDetect(currentFilePath);
            }
            else
            {
                // 使用指定编码
                var encoding = GetEncodingByName(encodingName);
                if (encoding != null)
                {
                    OpenFileWithSpecificEncoding(currentFilePath, encoding);
                }
            }
        }

        private void ReloadWithAutoDetect_Click(object sender, RoutedEventArgs e) => ReloadCurrentFile();
        private void ReloadWithUTF8NoBOM_Click(object sender, RoutedEventArgs e) => ReloadCurrentFile("UTF-8 (无BOM)");
        private void ReloadWithUTF8BOM_Click(object sender, RoutedEventArgs e) => ReloadCurrentFile("UTF-8 (带BOM)");
        private void ReloadWithGBK_Click(object sender, RoutedEventArgs e) => ReloadCurrentFile("GBK");
        private void ReloadWithGB2312_Click(object sender, RoutedEventArgs e) => ReloadCurrentFile("GB2312");
        private void ReloadWithUnicode_Click(object sender, RoutedEventArgs e) => ReloadCurrentFile("Unicode (UTF-16 LE)");

        private void SaveFile_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(currentFilePath))
            {
                SaveAsFile_Click(sender, e);
            }
            else
            {
                SaveFile(currentFilePath);
            }
        }

        private void SaveAsFile_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dialog = new SaveFileDialog
            {
                Filter = "文本文件 (*.txt)|*.txt|Markdown文件 (*.md)|*.md|Mermaid文件 (*.mmd)|*.mmd|所有文件 (*.*)|*.*",
                FilterIndex = 1,  // 默认选择"文本文件"
                Title = "另存为"
            };

            if (dialog.ShowDialog() == true)
            {
                SaveFile(dialog.FileName);
                currentFilePath = dialog.FileName;
            }
        }

        private void SaveFile(string filePath)
        {
            try
            {
                File.WriteAllText(filePath, TextEditor.Text, currentEncoding);
                StatusText.Text = $"已保存: {Path.GetFileName(filePath)}";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private async void ExportPNG_Click(object sender, RoutedEventArgs e)
        {
            await ExportImage("PNG");
        }

        private async void ExportSVG_Click(object sender, RoutedEventArgs e)
        {
            await ExportImage("SVG");
        }

        private async Task ExportImage(string format)
        {
            if (!isWebViewInitialized)
            {
                MessageBox.Show("WebView尚未初始化完成", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            SaveFileDialog dialog = new SaveFileDialog
            {
                Filter = format == "PNG" ? "PNG图片 (*.png)|*.png" : "SVG图片 (*.svg)|*.svg",
                Title = $"导出为{format}",
                FileName = GetDefaultExportFileName(format == "PNG" ? ".png" : ".svg")
            };

            if (dialog.ShowDialog() == true)
            {
                try
                {
                    // 1. 保存当前的缩放和平移状态
                    var currentState = await SaveZoomState();
                    Debug.WriteLine($"导出前保存状态: {currentState}");
                    
                    // 2. 重置缩放和位置，确保导出完整内容
                    await ResetPreviewZoom();
                    StatusText.Text = $"正在准备导出{format}...";
                    
                    // 3. 等待DOM更新和渲染完成
                    await Task.Delay(300);
                    
                    if (format == "PNG")
                    {
                        // 截图方式导出PNG
                        using (var fileStream = File.Create(dialog.FileName))
                        {
                            await PreviewWebView.CoreWebView2.CapturePreviewAsync(
                                CoreWebView2CapturePreviewImageFormat.Png, 
                                fileStream);
                        }
                        
                        StatusText.Text = $"已导出PNG: {Path.GetFileName(dialog.FileName)}";
                    }
                    else
                    {
                        // 导出SVG
                        string script = @"
                            (function() {
                                const svg = document.querySelector('#preview-container svg');
                                if (svg) {
                                    return svg.outerHTML;
                                }
                                return null;
                            })();
                        ";
                        
                        string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                        if (result != "null")
                        {
                            // 去除JSON转义
                            string svgContent = System.Text.Json.JsonSerializer.Deserialize<string>(result) ?? "";
                            File.WriteAllText(dialog.FileName, svgContent, new UTF8Encoding(false));
                            StatusText.Text = $"已导出SVG: {Path.GetFileName(dialog.FileName)}";
                        }
                        else
                        {
                            MessageBox.Show("未找到SVG内容，请先渲染Mermaid图表", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }
                    }
                    
                    // 4. 询问用户是否恢复之前的视图状态
                    if (!string.IsNullOrEmpty(currentState) && currentState != "1,0,0")
                    {
                        var restore = MessageBox.Show(
                            "导出成功！\n\n是否恢复之前的缩放和位置？\n\n点击\"是\"恢复，点击\"否\"保持初始视图。",
                            "导出完成",
                            MessageBoxButton.YesNo,
                            MessageBoxImage.Question);
                        
                        if (restore == MessageBoxResult.Yes)
                        {
                            await RestoreZoomState(currentState);
                            StatusText.Text = $"已导出并恢复视图: {Path.GetFileName(dialog.FileName)}";
                        }
                        else
                        {
                            StatusText.Text = $"已导出{format}: {Path.GetFileName(dialog.FileName)}";
                        }
                    }
                    else
                    {
                        StatusText.Text = $"已导出{format}: {Path.GetFileName(dialog.FileName)}";
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"导出失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    StatusText.Text = "导出失败";
                }
            }
        }

        private async void PreviewMode_None(object sender, RoutedEventArgs e)
        {
            await SetPreviewMode(PreviewMode.None);
        }

        private async void PreviewMode_Mermaid(object sender, RoutedEventArgs e)
        {
            await SetPreviewMode(PreviewMode.Mermaid);
        }

        private async void PreviewMode_Markdown(object sender, RoutedEventArgs e)
        {
            await SetPreviewMode(PreviewMode.Markdown);
        }

        private async Task SetPreviewMode(PreviewMode mode)
        {
            Debug.WriteLine($"=== SetPreviewMode 调用 ===");
            Debug.WriteLine($"  参数 mode = {mode}");
            Debug.WriteLine($"  调用前 currentPreviewMode = {currentPreviewMode}");
            Debug.WriteLine($"  isWebViewInitialized = {isWebViewInitialized}");
            
            // ⚠️ 如果传入 None，显示警告
            if (mode == PreviewMode.None)
            {
                Debug.WriteLine("⚠️ 警告：尝试设置预览模式为 None，这会关闭预览！");
            }
            
            currentPreviewMode = mode;

            if (mode == PreviewMode.None)
            {
                // 关闭预览
                PreviewColumn.Width = new GridLength(0);
                PreviewPanel.Visibility = Visibility.Collapsed;
                PreviewModeText.Text = "按F5开启预览";
                PreviewModeText.Foreground = System.Windows.Media.Brushes.Gray;
                StatusText.Text = "预览已关闭";
            }
            else
            {
                // 显示预览
                PreviewColumn.Width = new GridLength(1, GridUnitType.Star);
                PreviewPanel.Visibility = Visibility.Visible;
                PreviewModeText.Foreground = System.Windows.Media.Brushes.Black;

                if (mode == PreviewMode.Mermaid)
                {
                    PreviewModeText.Text = "Mermaid";
                    if (isWebViewInitialized)
                    {
                        await RenderMermaid();
                    }
                }
                else if (mode == PreviewMode.Markdown)
                {
                    PreviewModeText.Text = "Markdown";
                    if (isWebViewInitialized)
                    {
                        await RenderMarkdown();
                    }
                }
            }
        }

        private async void ExportHTML_Click(object sender, RoutedEventArgs e)
        {
            if (currentPreviewMode == PreviewMode.None)
            {
                MessageBox.Show("请先启用预览模式", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            SaveFileDialog dialog = new SaveFileDialog
            {
                Filter = "HTML文件 (*.html)|*.html",
                Title = "导出为HTML",
                FileName = GetDefaultExportFileName(".html")
            };

            if (dialog.ShowDialog() == true)
            {
                try
                {
                    string script = @"document.getElementById('preview-container').innerHTML";
                    string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                    string content = System.Text.Json.JsonSerializer.Deserialize<string>(result) ?? "";

                    string html = $@"<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>{Path.GetFileNameWithoutExtension(dialog.FileName)}</title>
    <style>
        body {{
            margin: 20px;
            padding: 0;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
            line-height: 1.6;
        }}
        h1, h2 {{ border-bottom: 1px solid #eaecef; padding-bottom: 0.3em; }}
        code {{
            background-color: #f6f8fa;
            border-radius: 3px;
            padding: 2px 4px;
            font-family: Consolas, Monaco, monospace;
        }}
        pre {{
            background-color: #f6f8fa;
            border-radius: 3px;
            padding: 16px;
            overflow: auto;
        }}
    </style>
</head>
<body>
{content}
</body>
</html>";

                    File.WriteAllText(dialog.FileName, html, new UTF8Encoding(false));
                    StatusText.Text = $"已导出HTML: {Path.GetFileName(dialog.FileName)}";
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"导出失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void Exit_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private async void CheckPreview_Click(object sender, RoutedEventArgs e)
        {
            var status = new System.Text.StringBuilder();
            status.AppendLine("=== 预览功能状态 ===\n");
            
            status.AppendLine($"WebView2 初始化: {(isWebViewInitialized ? "✓ 成功" : "✗ 失败")}");
            status.AppendLine($"当前预览模式: {GetPreviewModeName()}");
            status.AppendLine($"自动渲染: {(autoRender ? "✓ 已启用" : "✗ 已禁用")}");
            
            if (PreviewWebView?.CoreWebView2 != null)
            {
                status.AppendLine($"WebView2 版本: {PreviewWebView.CoreWebView2.Environment.BrowserVersionString}");
                
                // 检查 JavaScript 库加载状态
                try
                {
                    string checkMarked = "typeof marked !== 'undefined' ? 'loaded' : 'missing'";
                    string markedResult = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(checkMarked);
                    string markedStatus = markedResult.Trim().Trim('"');
                    status.AppendLine($"Marked.js 库: {(markedStatus == "loaded" ? "✓ 已加载" : "✗ 未加载")}");
                    
                    string checkMermaid = "typeof window.mermaid !== 'undefined' ? 'loaded' : 'missing'";
                    string mermaidResult = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(checkMermaid);
                    string mermaidStatus = mermaidResult.Trim().Trim('"');
                    status.AppendLine($"Mermaid.js 库: {(mermaidStatus == "loaded" ? "✓ 已加载" : "✗ 未加载")}");
                    
                    // 检查渲染函数
                    string checkRenderMermaid = "typeof window.renderMermaid === 'function' ? 'ok' : 'missing'";
                    string renderMermaidResult = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(checkRenderMermaid);
                    string renderMermaidStatus = renderMermaidResult.Trim().Trim('"');
                    status.AppendLine($"Mermaid渲染函数: {(renderMermaidStatus == "ok" ? "✓ 正常" : "✗ 缺失")}");
                    
                    string checkRenderMarkdown = "typeof window.renderMarkdown === 'function' ? 'ok' : 'missing'";
                    string renderMarkdownResult = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(checkRenderMarkdown);
                    string renderMarkdownStatus = renderMarkdownResult.Trim().Trim('"');
                    status.AppendLine($"Markdown渲染函数: {(renderMarkdownStatus == "ok" ? "✓ 正常" : "✗ 缺失")}");
                }
                catch (Exception ex)
                {
                    status.AppendLine($"检查失败: {ex.Message}");
                }
            }
            else
            {
                status.AppendLine("WebView2: ✗ 未加载");
            }
            
            status.AppendLine($"\n预览面板可见: {(PreviewPanel.Visibility == Visibility.Visible ? "是" : "否")}");
            
            status.AppendLine("\n=== 建议 ===");
            if (!isWebViewInitialized)
            {
                status.AppendLine("• 请检查网络连接");
                status.AppendLine("• 确保已安装 WebView2 Runtime");
                status.AppendLine("• 尝试重启应用程序");
            }
            else if (currentPreviewMode == PreviewMode.None)
            {
                status.AppendLine("• 点击\"预览\"菜单启用预览模式");
                status.AppendLine("• 尝试点击\"测试预览渲染\"进行测试");
            }
            else
            {
                status.AppendLine("• 如果库未加载，检查网络连接");
                status.AppendLine("• 点击\"测试预览渲染\"验证功能");
                status.AppendLine("• 输入内容后会在1秒后自动渲染");
            }
            
            MessageBox.Show(status.ToString(), "预览功能状态", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        private async void TestPreview_Click(object sender, RoutedEventArgs e)
        {
            if (!isWebViewInitialized)
            {
                MessageBox.Show("WebView2 尚未初始化", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            var testMode = MessageBox.Show("选择测试类型：\n\n是(Y) = 测试 Markdown\n否(N) = 测试 Mermaid", 
                "测试预览", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);

            if (testMode == MessageBoxResult.Cancel)
                return;

            try
            {
                if (testMode == MessageBoxResult.Yes)
                {
                    // 测试 Markdown
                    string testMarkdown = "# 测试标题\\n\\n这是一个 **粗体** 测试。\\n\\n- 项目1\\n- 项目2";
                    string script = $"window.renderMarkdown(\"{testMarkdown}\")";
                    string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                    
                    MessageBox.Show($"Markdown 测试完成\n返回值: {result}\n\n如果右侧显示了格式化文本，说明功能正常。", 
                        "测试结果", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                else
                {
                    // 测试 Mermaid
                    string testMermaid = "graph TD\\n    A[测试] --> B[成功]";
                    string script = $"window.renderMermaid(\"{testMermaid}\")";
                    string result = await PreviewWebView.CoreWebView2.ExecuteScriptAsync(script);
                    
                    MessageBox.Show($"Mermaid 测试完成\n返回值: {result}\n\n如果右侧显示了流程图，说明功能正常。", 
                        "测试结果", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"测试失败:\n{ex.Message}\n\n这表明 JavaScript 库可能未正确加载。\n请检查网络连接。", 
                    "测试失败", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private string GetPreviewModeName()
        {
            return currentPreviewMode switch
            {
                PreviewMode.None => "关闭",
                PreviewMode.Mermaid => "Mermaid 图表",
                PreviewMode.Markdown => "Markdown 文档",
                _ => "未知"
            };
        }

        private void About_Click(object sender, RoutedEventArgs e)
        {
            var about = new System.Text.StringBuilder();
            about.AppendLine("Mermaid 文本编辑器");
            about.AppendLine("版本 2.0");
            about.AppendLine();
            about.AppendLine("一个支持多种编码、Markdown 和 Mermaid 的");
            about.AppendLine("多功能文本编辑器");
            about.AppendLine();
            about.AppendLine("技术栈:");
            about.AppendLine("• .NET 8.0 + WPF");
            about.AppendLine("• WebView2");
            about.AppendLine("• Mermaid.js v10");
            about.AppendLine("• Marked.js v11");
            about.AppendLine();
            about.AppendLine("© 2025 - 供学习和个人使用");
            
            MessageBox.Show(about.ToString(), "关于", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        // 编码设置方法（统一处理）
        private void SetEncoding(string encodingName)
        {
            var encoding = GetEncodingByName(encodingName);
            if (encoding != null)
            {
                currentEncoding = encoding;
            UpdateEncodingInfo();
            }
        }

        private void SetEncoding_UTF8NoBOM(object sender, RoutedEventArgs e) => SetEncoding("UTF-8 (无BOM)");
        private void SetEncoding_UTF8BOM(object sender, RoutedEventArgs e) => SetEncoding("UTF-8 (带BOM)");
        private void SetEncoding_GBK(object sender, RoutedEventArgs e) => SetEncoding("GBK");
        private void SetEncoding_GB2312(object sender, RoutedEventArgs e) => SetEncoding("GB2312");
        private void SetEncoding_Unicode(object sender, RoutedEventArgs e) => SetEncoding("Unicode (UTF-16 LE)");
        private void SetEncoding_ASCII(object sender, RoutedEventArgs e) => SetEncoding("ASCII");

        // 更新状态栏的编码信息显示
        private void UpdateEncodingInfo()
        {
            EncodingText.Text = GetEncodingDisplayName(currentEncoding);
        }

        private Encoding DetectEncoding(string filePath)
        {
            // 读取文件内容进行检测
            byte[] buffer = File.ReadAllBytes(filePath);
            
            if (buffer.Length == 0)
                return new UTF8Encoding(false);

            // 1. 检测BOM标记
            if (buffer.Length >= 3 && buffer[0] == 0xEF && buffer[1] == 0xBB && buffer[2] == 0xBF)
                return new UTF8Encoding(true);

            if (buffer.Length >= 2 && buffer[0] == 0xFF && buffer[1] == 0xFE)
                return Encoding.Unicode;

            if (buffer.Length >= 2 && buffer[0] == 0xFE && buffer[1] == 0xFF)
                return Encoding.BigEndianUnicode;

            if (buffer.Length >= 4 && buffer[0] == 0xFF && buffer[1] == 0xFE && buffer[2] == 0x00 && buffer[3] == 0x00)
                return Encoding.UTF32;

            // 2. 尝试UTF-8解码（无BOM）
            if (IsValidUtf8(buffer))
                return new UTF8Encoding(false);

            // 3. 检测GBK/GB2312特征
            if (IsLikelyGbk(buffer))
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                return Encoding.GetEncoding("GBK");
            }

            // 4. 默认UTF-8
            return new UTF8Encoding(false);
        }

        // 检测是否为有效的UTF-8编码
        private bool IsValidUtf8(byte[] bytes)
        {
            try
            {
                var decoder = Encoding.UTF8.GetDecoder();
                int charCount = decoder.GetCharCount(bytes, 0, bytes.Length, true);
                char[] chars = new char[charCount];
                decoder.GetChars(bytes, 0, bytes.Length, chars, 0, true);
                
                // 检查是否有无效字符（替换字符）
                string text = new string(chars);
                int replacementChars = text.Count(c => c == '\uFFFD');
                
                // 如果替换字符少于1%，认为是有效的UTF-8
                return replacementChars < bytes.Length * 0.01;
            }
            catch
            {
                return false;
            }
        }

        // 检测是否可能是GBK/GB2312编码
        private bool IsLikelyGbk(byte[] bytes)
        {
            int gbkChars = 0;
            int totalBytes = bytes.Length;

            for (int i = 0; i < bytes.Length - 1; i++)
            {
                // GBK编码范围：
                // 第一字节：0x81-0xFE
                // 第二字节：0x40-0x7E 或 0x80-0xFE
                if (bytes[i] >= 0x81 && bytes[i] <= 0xFE)
                {
                    if ((bytes[i + 1] >= 0x40 && bytes[i + 1] <= 0x7E) ||
                        (bytes[i + 1] >= 0x80 && bytes[i + 1] <= 0xFE))
                    {
                        gbkChars++;
                        i++; // 跳过下一个字节
                    }
                }
            }

            // 如果GBK字符对数量占比超过30%，认为是GBK编码
            return gbkChars > 0 && (gbkChars * 2.0 / totalBytes) > 0.3;
        }

        private bool ConfirmSaveChanges()
        {
            // 这里可以添加检查文件是否修改的逻辑
            return true;
        }

        // 获取导出时的默认文件名
        private string GetDefaultExportFileName(string extension)
        {
            if (!string.IsNullOrEmpty(currentFilePath))
            {
                // 使用当前打开的文件名（不带扩展名）+ 新扩展名
                return Path.GetFileNameWithoutExtension(currentFilePath) + extension;
            }
            
            // 如果没有打开文件，使用默认名称
            return "export" + extension;
        }

        #region 文件关联功能

        // 检查是否以管理员权限运行
        private bool IsRunningAsAdministrator()
        {
            var identity = WindowsIdentity.GetCurrent();
            var principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        // 以管理员权限重启应用程序
        private void RestartAsAdministrator(string args = "")
        {
            try
            {
                var processInfo = new ProcessStartInfo
                {
                    FileName = Process.GetCurrentProcess().MainModule?.FileName ?? "",
                    UseShellExecute = true,
                    Verb = "runas", // 请求管理员权限
                    Arguments = args
                };

                Process.Start(processInfo);
                Application.Current.Shutdown();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"获取管理员权限失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // 注册文件关联
        private void RegisterFileAssociation(string extension, string progId, string description)
        {
            if (!IsRunningAsAdministrator())
            {
                var result = MessageBox.Show(
                    "注册文件关联需要管理员权限。\n是否以管理员身份重启应用程序？",
                    "需要管理员权限",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question);

                if (result == MessageBoxResult.Yes)
                {
                    RestartAsAdministrator($"/register:{extension}");
                }
                return;
            }

            try
            {
                string exePath = Process.GetCurrentProcess().MainModule?.FileName ?? "";

                // 注册 ProgId
                using (var key = Registry.ClassesRoot.CreateSubKey(progId))
                {
                    if (key != null)
                    {
                        key.SetValue("", description);
                        
                        // 设置图标（使用可执行文件中嵌入的图标）
                        using (var iconKey = key.CreateSubKey("DefaultIcon"))
                        {
                            // ",0" 表示使用 .exe 文件中的第一个图标
                            iconKey?.SetValue("", $"\"{exePath}\",0");
                        }

                        // 设置打开命令
                        using (var commandKey = key.CreateSubKey(@"shell\open\command"))
                        {
                            commandKey?.SetValue("", $"\"{exePath}\" \"%1\"");
                        }
                    }
                }

                // 关联扩展名到 ProgId
                using (var key = Registry.ClassesRoot.CreateSubKey(extension))
                {
                    if (key != null)
                    {
                        key.SetValue("", progId);
                    }
                }

                // 通知系统文件关联已更改
                NativeMethods.SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);

                MessageBox.Show($"已成功注册 {extension} 文件关联！", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
                StatusText.Text = $"已注册 {extension} 文件关联";
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("权限不足，无法修改注册表。请以管理员身份运行程序。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"注册文件关联失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // 取消文件关联
        private void UnregisterFileAssociation(string extension, string progId)
        {
            if (!IsRunningAsAdministrator())
            {
                var result = MessageBox.Show(
                    "取消文件关联需要管理员权限。\n是否以管理员身份重启应用程序？",
                    "需要管理员权限",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question);

                if (result == MessageBoxResult.Yes)
                {
                    RestartAsAdministrator($"/unregister:{extension}");
                }
                return;
            }

            try
            {
                // 检查扩展名是否关联到我们的程序
                using (var key = Registry.ClassesRoot.OpenSubKey(extension))
                {
                    if (key != null)
                    {
                        string? currentProgId = key.GetValue("")?.ToString();
                        if (currentProgId != progId)
                        {
                            MessageBox.Show($"{extension} 文件未关联到本程序。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                            return;
                        }
                    }
                    else
                    {
                        MessageBox.Show($"{extension} 文件未关联到任何程序。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                        return;
                    }
                }

                // 删除扩展名关联
                Registry.ClassesRoot.DeleteSubKeyTree(extension, false);

                // 删除 ProgId
                Registry.ClassesRoot.DeleteSubKeyTree(progId, false);

                // 通知系统文件关联已更改
                NativeMethods.SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);

                MessageBox.Show($"已成功取消 {extension} 文件关联！", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
                StatusText.Text = $"已取消 {extension} 文件关联";
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("权限不足，无法修改注册表。请以管理员身份运行程序。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"取消文件关联失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // 检查文件关联状态
        private string CheckFileAssociationStatus(string extension, string progId)
        {
            try
            {
                using (var key = Registry.ClassesRoot.OpenSubKey(extension))
                {
                    if (key != null)
                    {
                        string? currentProgId = key.GetValue("")?.ToString();
                        if (currentProgId == progId)
                        {
                            return "✓ 已关联到本程序";
                        }
                        else
                        {
                            return $"✗ 已关联到其他程序 ({currentProgId})";
                        }
                    }
                    else
                    {
                        return "✗ 未关联";
                    }
                }
            }
            catch
            {
                return "✗ 无法检查（权限不足）";
            }
        }

        // 执行文件关联命令（由App.xaml.cs调用）
        public void ExecuteFileAssociationCommand(string command, string extension)
        {
            string progId = $"MermaidTextEditor{extension}";
            string description = extension switch
            {
                ".mmd" => "Mermaid Diagram File",
                ".md" => "Markdown File",
                ".txt" => "Text File",
                _ => "Text File"
            };

            if (command == "register")
            {
                RegisterFileAssociation(extension, progId, description);
            }
            else if (command == "unregister")
            {
                UnregisterFileAssociation(extension, progId);
            }
        }

        // 菜单事件处理
        private void RegisterMmd_Click(object sender, RoutedEventArgs e)
        {
            RegisterFileAssociation(".mmd", "MermaidTextEditor.mmd", "Mermaid Diagram File");
        }

        private void RegisterMd_Click(object sender, RoutedEventArgs e)
        {
            RegisterFileAssociation(".md", "MermaidTextEditor.md", "Markdown File");
        }

        private void RegisterTxt_Click(object sender, RoutedEventArgs e)
        {
            RegisterFileAssociation(".txt", "MermaidTextEditor.txt", "Text File");
        }

        private void UnregisterMmd_Click(object sender, RoutedEventArgs e)
        {
            UnregisterFileAssociation(".mmd", "MermaidTextEditor.mmd");
        }

        private void UnregisterMd_Click(object sender, RoutedEventArgs e)
        {
            UnregisterFileAssociation(".md", "MermaidTextEditor.md");
        }

        private void UnregisterTxt_Click(object sender, RoutedEventArgs e)
        {
            UnregisterFileAssociation(".txt", "MermaidTextEditor.txt");
        }

        private void CheckFileAssociation_Click(object sender, RoutedEventArgs e)
        {
            var status = new StringBuilder();
            status.AppendLine("=== 文件关联状态 ===\n");
            status.AppendLine($"当前运行权限: {(IsRunningAsAdministrator() ? "管理员" : "普通用户")}\n");
            
            status.AppendLine($".mmd 文件: {CheckFileAssociationStatus(".mmd", "MermaidTextEditor.mmd")}");
            status.AppendLine($".md 文件: {CheckFileAssociationStatus(".md", "MermaidTextEditor.md")}");
            status.AppendLine($".txt 文件: {CheckFileAssociationStatus(".txt", "MermaidTextEditor.txt")}");
            
            status.AppendLine("\n=== 说明 ===");
            status.AppendLine("• 注册/取消文件关联需要管理员权限");
            status.AppendLine("• 注册后可以双击文件直接打开");
            status.AppendLine("• 可以随时取消文件关联");

            MessageBox.Show(status.ToString(), "文件关联状态", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        #endregion
    }

    // 用于通知Windows文件关联更改的原生方法
    internal static class NativeMethods
    {
        [System.Runtime.InteropServices.DllImport("shell32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
        public static extern void SHChangeNotify(int wEventId, int uFlags, IntPtr dwItem1, IntPtr dwItem2);
    }
}

